package client.tutorial;

import jp.fores.midori.client.RPCClient;
import jp.fores.midori.client.caller.GeneralURLListGetter;
import jp.fores.midori.client.caller.ParallelRPCClientCaller;
import jp.fores.midori.client.caller.RPCClientCaller;
import jp.fores.midori.client.caller.RepeatRPCClientCaller;
import jp.fores.midori.client.caller.TimeoutRPCClientCaller;
import jp.fores.midori.client.caller.URLListGetter;
import jp.fores.midori.client.handler.BasicRPCHandler;
import jp.fores.midori.client.handler.RPCHandler;
import jp.fores.midori.client.serializer.JsonRPCSerializer;
import jp.fores.midori.client.serializer.RPCSerializer;
import tutorial.dto.CalcResultDto;

/**
 * RPCClientCallerの少し複雑な使い方のサンプルクラス。<br>
 * 動作確認用の3つのサーバー(http://1.latest.midori-rpc.appspot.com/, http://2.latest.midori-rpc.appspot.com/, 
 * http://3.latest.midori-rpc.appspot.com/)のCalcServiceに対してJSON-RPCを行います。<br>
 */
public class ComplexRPCClientCallerSample {
	//==========================================================
	//メソッド

	//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	//クラスメソッド

	/**
	 * メインメソッドです。
	 *
	 * @param args コマンドライン引数
	 * @throws Exception 例外
	 */
	public static void main(String[] args) throws Exception {
		//==========================================================
		//呼び出し先のURL
		//(複数存在するので配列)
		String[] urlArray = new String[] {
				"http://1.latest.midori-rpc.appspot.com/rpc/calcService.json",
				"http://2.latest.midori-rpc.appspot.com/rpc/calcService.json",
				"http://3.latest.midori-rpc.appspot.com/rpc/calcService.json" };

		//呼び出し先のURLに応じたURLListGetterのインスタンスを生成
		URLListGetter urlListGetter = new GeneralURLListGetter(urlArray);


		//==========================================================
		//RPCClientの準備

		//RPC形式に応じたシリアライザのインスタンスを生成
		//(JSON-RPCなので、JsonRPCSerializerを使う)
		RPCSerializer serializer = new JsonRPCSerializer();

		//使用するライブラリに応じたハンドラのインスタンスを生成
		//(Java標準ライブラリを使いたいので、BasicRPCHandlerを使う)
		RPCHandler handler = new BasicRPCHandler();

		//シリアライザとハンドラを元にして、RPCClientのインスタンスを生成
		RPCClient rpcClient = new RPCClient(serializer, handler);


		//==========================================================
		//RPCClientCallerの準備

		//複数のサーバーに対して並列にRPCを行うRPCClientCallerの実装クラスのインスタンスを生成
		RPCClientCaller caller = new ParallelRPCClientCaller(rpcClient);

		//並列ではなく、順番にRPCを行う場合はこちら
		//RPCClientCaller caller = new SequenceRPCClientCaller(rpcClient);

		//繰り返し回数指定付きでRPCを行えるようにするために、RepeatRPCClientCallerでラッピングする
		//(成功するまで、無限に繰り返したいので-1を指定する)
		caller = new RepeatRPCClientCaller(caller, -1);

		//さらに、タイムアウト指定付きでRPCを行えるようにするために、TimeoutRPCClientCallerでラッピングする
		//(全体のタイムアウト時間として、10000ミリ秒(10秒)を指定する)
		caller = new TimeoutRPCClientCaller(caller, 10000);


		//==========================================================
		//RPCの実行

		//RPCで「operation」メソッドを呼び出す
		//(戻り値の型指定を行う)
		//(64, 4は「operation」メソッドに渡す引数)
		CalcResultDto result = caller.remoteCall(CalcResultDto.class, urlListGetter, "operation", 64, 4);

		//結果の出力
		System.out.println("足し算=" + result.addition + ", 引き算="
				+ result.subtraction + ", かけ算=" + result.multiplication
				+ ", 割り算=" + result.division);
	}
}
